package org.rui.rpc.service;

import io.vertx.core.Handler;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerResponse;
import org.rui.rpc.model.RpcRequest;
import org.rui.rpc.model.RpcResponse;
import org.rui.rpc.registry.LocalRegistry;
import org.rui.rpc.serializer.JDKSerializer;
import org.rui.rpc.serializer.Serializer;

import java.io.IOException;
import java.lang.reflect.Method;

/**
 * @author: linweirui
 * @date: 2024/12/02 14:52
 */

/**
 * 请求处理器，接受处理客户端代理对象请求处理，
 * 发送的请求一般在请求体中附带序列化好的RpcRequest
 * 一接受http请求就执行handle方法，执行反序列化后利用反射调用对应的服务
 * 接着封装反射后的结果响应给客户端（调用服务者）
 */
public class HttpServerHandler implements Handler<HttpServerRequest> {

    @Override
    public void handle(HttpServerRequest request) {
        //指定序列化器
        JDKSerializer serializer = new JDKSerializer();
        //打印日志
        System.out.println("Receive request " + request.method() + " url: " + request.uri());
        //处理http请求
        request.handler(body -> {
            byte[] bytes = body.getBytes();
            RpcRequest rpcRequest = null;
            try {
                //反序列化为对应的对象
                rpcRequest = serializer.deserialize(bytes, RpcRequest.class);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            //构造响应结果
            RpcResponse rpcResponse = new RpcResponse();
            if (rpcRequest == null) {
                System.out.println("rpcRequest is null");
                doResponse(request, rpcResponse, serializer);
                return;
            }
            //获取调用的服务
            Class<?> service = LocalRegistry.getService(rpcRequest.getServiceName());
            try {
                //获取调用的方法并反射执行
                Method method = service.getMethod(rpcRequest.getMethodName(), rpcRequest.getParameterTypes());
                Object result = method.invoke(service.newInstance(), rpcRequest.getArgs());

                //封装返回结果
                rpcResponse.setData(result);
                rpcResponse.setMessage("ok");
                rpcResponse.setDataType(method.getReturnType());
            } catch (Exception e) {
                e.printStackTrace();
                rpcResponse.setException(e);
                rpcResponse.setMessage(e.getMessage());
            }
            // 响应
            doResponse(request, rpcResponse, serializer);
        });
    }

    /**
     * 设置响应信息
     *
     * @param request
     * @param rpcResponse
     * @param serializer
     */
    void doResponse(HttpServerRequest request, RpcResponse rpcResponse, Serializer serializer) {
        HttpServerResponse httpServerResponse = request.response()
                .putHeader("content-type", "application/json");
        try {
            byte[] serialized = serializer.serialize(rpcResponse);
            httpServerResponse.end(Buffer.buffer(serialized));
        } catch (IOException e) {
            e.printStackTrace();
            httpServerResponse.end(Buffer.buffer());
        }
    }
}
